﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MySql.Data.MySqlClient;
using System.Data;
using DalGen.Interf;
using NVelocity.App;
using NVelocity;
using Commons.Collections;
using NVelocity.Runtime;
using DalGen.Entity;
using System.IO;
using System.Xml;
using DalGen.Util;

namespace DalGen.Impl
{
	public class MySqlBuilder : BuilderBase,IBuilder
	{
		protected MySqlConnection _conn;

		
		public MySqlBuilder()
		{
			string sSplit = System.AppDomain.CurrentDomain.BaseDirectory.Substring(System.AppDomain.CurrentDomain.BaseDirectory.Length - 1);
			string ConfigPath;
			if (sSplit != @"\" && sSplit != "/")
				ConfigPath = System.AppDomain.CurrentDomain.BaseDirectory + @"\";
			else
				ConfigPath = System.AppDomain.CurrentDomain.BaseDirectory;
            string sConfigFileName = ConfigPath + @"Reflection\MySQL2DotNet.xml";
			domSql2DotNet = new XmlDocument();
			domSql2DotNet.Load(sConfigFileName);

		}


		public  void ConnectToDB()
		{
			string sConnString = ConnectionString;
			_conn = new MySqlConnection(sConnString);
			_conn.Open();
		}

		public  void DisconnectFromDB()
		{
			if (_conn.State == ConnectionState.Open)
			{
				_conn.Close();
			}
		}

		public  System.Data.DataTable GetAllTables()
		{
			ConnectToDB();
			DataTable dtTables = new DataTable();
			MySqlDataAdapter da = new MySqlDataAdapter();


			da.SelectCommand = new MySqlCommand("show tables", _conn);
			da.Fill(dtTables);
			DisconnectFromDB();
			return dtTables;
		}

		// 获取指定表的主键
		public DataTable GetPrimaryKeys(string sTableName)
		{
			//show index from UserConfigV2 where Key_name='PRIMARY'

			DataTable dtPkey = new DataTable("PrimaryKeys");
			string strSql = "show index from " + sTableName + " where Key_name='PRIMARY'";

			MySqlDataAdapter da = new MySqlDataAdapter();
			da.SelectCommand = new MySqlCommand(strSql, _conn);
			da.Fill(dtPkey);
			return dtPkey;
		}


		public List<TableInfo> GetColumns(string dataBaseName, string sTableName)
		{
			//string strSql = @"SHOW FULL COLUMNS FROM " + sTableName;

            string strSql = @"select  COLUMN_NAME, DATA_TYPE,CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE,COLUMN_KEY,COLUMN_COMMENT,EXTRA from information_schema.COLUMNS where TABLE_SCHEMA='" + dataBaseName + "' and   TABLE_NAME='" + sTableName + "'"; 

			// 获取字段
			DataTable dtColumn = new DataTable("Columns");
			MySqlDataAdapter da = new MySqlDataAdapter();
			da.SelectCommand = new MySqlCommand(strSql, _conn);
			da.Fill(dtColumn);

			// 获取表的主键
			DataTable dtPkey = GetPrimaryKeys(sTableName);

			List<TableInfo> list = new List<TableInfo>();

			foreach (DataRow row in dtColumn.Rows)
			{
				TableInfo entity = new TableInfo();
				string sDataType = row["DATA_TYPE"].ToString();

				entity.ColumnName = row["COLUMN_NAME"].ToString();

				// 判断列是否为主键
				if (dtPkey.Select("COLUMN_NAME='" + (string)row["COLUMN_NAME"] + "'").Length != 0)
					entity.IsPK = true;
				else
					entity.IsPK = false;

                if (row["EXTRA"].ToString() == "auto_increment")
                {
                    entity.Identity = true;

                }
                else
                {
                    entity.Identity = false;
                }

                if (string.IsNullOrEmpty(row["COLUMN_COMMENT"].ToString()))
                {
                    entity.Remark = row["COLUMN_NAME"].ToString();
                }
                else
                {
                    entity.Remark = row["COLUMN_COMMENT"].ToString().Replace("\r\n", "");
                }


				entity.Type = GetLanguageTypeName(sDataType);

				entity.DbType = GetDbTypeName(sDataType);

				list.Add(entity);

			}

			return list;
		}


		public string BuilderEntity(BuilderInfo info)
		{

			
			//从文件中读取模板
			Template template = velocity.GetTemplate("Template/IBatis/DataEntity.vm");
			context.Put("list", info);

			//合并模板
			StringWriter writer = new StringWriter();
			template.Merge(context, writer);

            DirectoryInfo dic = new DirectoryInfo(info.EntitySavePath);
            dic.Create();

            using (StreamWriter writerFile = new StreamWriter(info.EntitySavePath + "/E"+info.TableName+".cs", false, Encoding.UTF8, 200))
            {
                writerFile.Write(writer);
                writerFile.Flush();
                writerFile.Close();
            }

			return writer.ToString();
		}


        public string BuilderMap(BuilderInfo info)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/Mapping.vm");
            context.Put("list", info);
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            DirectoryInfo dic = new DirectoryInfo(info.MapXmlSavePath);
            dic.Create();

            using (StreamWriter writerFile = new StreamWriter(info.MapXmlSavePath + "/" + info.TableName + ".xml", false, Encoding.UTF8, 200))
            {
                writerFile.Write(writer);
                writerFile.Flush();
                writerFile.Close();
            }



            return writer.ToString();
        }


        public string BuilderIRepository(BuilderInfo info)
        {

            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/IRepository.vm");
            context.Put("list", info);
            context.Put("StringHelper", new StringHelper());
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            DirectoryInfo dic = new DirectoryInfo(info.IRepositorySavePath);
            dic.Create();

            using (StreamWriter writerFile = new StreamWriter(info.IRepositorySavePath + "/I" + info.TableName + ".cs", false, Encoding.UTF8, 200))
            {
                writerFile.Write(writer);
                writerFile.Flush();
                writerFile.Close();
            }


            return writer.ToString();
        }

		public string BuilderIService(BuilderInfo info)
		{

			//从文件中读取模板
			Template template = velocity.GetTemplate("Template/IBatis/IService.vm");
			context.Put("list", info);
			context.Put("StringHelper", new StringHelper());
			//合并模板
			StringWriter writer = new StringWriter();
			template.Merge(context, writer);

			DirectoryInfo dic = new DirectoryInfo(info.IServiceSavePath);
			dic.Create();

			using (StreamWriter writerFile = new StreamWriter(info.IServiceSavePath + "/I" + info.TableName + "Service.cs", false, Encoding.UTF8, 200))
			{
				writerFile.Write(writer);
				writerFile.Flush();
				writerFile.Close();
			}


			return writer.ToString();
		}


		public string BuilderService(BuilderInfo info)
		{

			//从文件中读取模板
			Template template = velocity.GetTemplate("Template/IBatis/Service.vm");
			context.Put("list", info);
			context.Put("StringHelper", new StringHelper());
			//合并模板
			StringWriter writer = new StringWriter();
			template.Merge(context, writer);

			DirectoryInfo dic = new DirectoryInfo(info.ServiceSavePath);
			dic.Create();

			using (StreamWriter writerFile = new StreamWriter(info.ServiceSavePath + "/" + info.TableName + "Service.cs", false, Encoding.UTF8, 200))
			{
				writerFile.Write(writer);
				writerFile.Flush();
				writerFile.Close();
			}


			return writer.ToString();
		}

        public string ConnectionString { get; set; }


        public string BuilderRepository(BuilderInfo info)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/Repository.vm");
            context.Put("list", info);
            context.Put("StringHelper", new StringHelper());
            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            DirectoryInfo dic = new DirectoryInfo(info.RepositorySavePath);
            dic.Create();

            using (StreamWriter writerFile = new StreamWriter(info.RepositorySavePath + "/" + info.TableName + "Repository.cs", false, Encoding.UTF8, 200))
            {
                writerFile.Write(writer);
                writerFile.Flush();
                writerFile.Close();
            }


            return writer.ToString();
        }


        public string BuilderServiceModel(BuilderInfo info)
        {


            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/ServiceModel.vm");
            context.Put("list", info);

            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            DirectoryInfo dic = new DirectoryInfo(info.ServiceModelSavePath);
            dic.Create();

            using (StreamWriter writerFile = new StreamWriter(info.ServiceModelSavePath + "/" + info.TableName + "Model.cs", false, Encoding.UTF8, 200))
            {
                writerFile.Write(writer);
                writerFile.Flush();
                writerFile.Close();
            }

            return writer.ToString();
        }

        public string BuilderEntityToModel(BuilderInfo info)
        {

            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/EntityToModel.vm");
            context.Put("list", info);

            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            return writer.ToString();

        }

        public string BuilderModelToEntity(BuilderInfo info)
        {
            //从文件中读取模板
            Template template = velocity.GetTemplate("Template/IBatis/ModelToEntity.vm");
            context.Put("list", info);

            //合并模板
            StringWriter writer = new StringWriter();
            template.Merge(context, writer);

            return writer.ToString();

        }

    }
}
